package org.sgx.dao.test.test1;

import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;

import org.sgx.dao.*;
import org.sgx.dao.test.test1.testModel.BeanTest1;
import org.sgx.dao.test.test1.testModel.BeanTest2;
import org.sgx.dao.util.SQLUtil;
import org.sgx.dao.util.Util;

import junit.framework.TestCase;

public class DaoTest1 extends TestCase {

	private ConnectionGiver connectionGiver = null;

	@Override
	protected void setUp() throws Exception {
		super.setUp();				
	}
		
	public static ConnectionGiver getValidConnectionGiver() throws DaoException {
		String url = "jdbc:mysql://localhost:3306/";
		String dbName = "daotest1";
		String driver = "com.mysql.jdbc.Driver";
		String userName = "root";
		String password = "root";
		
		return new JDBCConnectionGiverNoClose(url, driver, dbName, userName, password);		
	}
	
	public void test1() throws DaoException{
		Dao<BeanTest1> dao1 = new BeanDao<BeanTest1>(getValidConnectionGiver(), BeanTest1.class);
		
		//first we drop the table and then recreate the table in database for having a clean table to work with
		dao1.dropTable(); 
		dao1.createTable();
		
		Date date1 = new Date();
		BeanTest1 bean1 = new BeanTest1("hello", 888l, true, date1);		
		assertTrue(dao1.listAll().size()==0);
		
		//add
		long newId = dao1.add(bean1);
		BeanTest1 bean1_ = dao1.get(newId);
		assertTrue(bean1.equals(bean1_));		
		assertEquals(bean1, bean1_);
		assertTrue(dao1.listAll().size()==1);
		
		//update
		bean1.setBoolField1(false);
		dao1.update(bean1);
		bean1_ = dao1.get(newId); /* BeanTest class is configured so longField1 field is its id */	
		assertTrue(!bean1_.getBoolField1());
				
		//dates test
		assertTrue(Util.dateEquals(bean1_.getDateField1(), date1));
				
		//delete
		dao1.remove(bean1);
		assertTrue(dao1.get(newId)==null);
		assertTrue(dao1.listAll().size()==0);
		
		//insert a lot
		bean1 = new BeanTest1("hello", 99999l, true, date1);	
		dao1.add(bean1);
		for(int i = 0; i<5; i++) {
//			Thread.sleep(200);
			bean1_ = new BeanTest1("string"+i, (long)i, i%2==0, new Date());
			dao1.add(bean1_);
		}
		
		bean1_ = dao1.get(bean1.getLongField1());
		assertEquals(bean1_, bean1);
		assertTrue(dao1.listAll().size()==6);		
	}
	
	
	public void testSearch() throws DaoException {
		Dao<BeanTest1> dao1 = new BeanDao<BeanTest1>(getValidConnectionGiver(), BeanTest1.class);
		
		//first we drop the table and then recreate the table in database for having a clean table to work with
		dao1.dropTable(); 
		dao1.createTable();
		
		//add some objects
		dao1.add(new BeanTest1("hello world", 0l, 1l, true, new Date()));
		dao1.add(new BeanTest1("edgar allan poe", 0l, 1l, true, new Date()));
		dao1.add(new BeanTest1("hi world", 0l, 12345l, true, new Date()));
		
		assertEquals(2, dao1.search(Util.toOrderedMap("strField1", "world")).size());
		assertEquals(1, dao1.search(Util.toOrderedMap("strField1", "edgar")).size());
		assertEquals(0, dao1.search(Util.<String>toOrderedMap(
			"strField1", "edgar", 
			"longField2", "666"), "and").size());
		assertEquals(1, dao1.search(Util.<String>toOrderedMap(
				"strField1", "hi", 
				"longField2", "12345"), "and").size());
		assertEquals(2, dao1.search(Util.<String>toOrderedMap(
				"strField1", "edgar", 
				"longField2", "12345"), "or").size());
		
		List<BeanTest1> result1 = dao1.search(Util.toOrderedMap("strField1", "world"));
		assertEquals(2, result1.size());
		assertTrue(result1.get(0)!=null); 
	}
	
	public void testLocale() throws DaoException {
	    Dao<BeanTest1> dao1 = new BeanDao<BeanTest1>(getValidConnectionGiver(), BeanTest1.class, "Test1_testLocale");
		
	    //first we drop the table and then recreate the table in database for having a clean table to work with
		dao1.dropTable(); 
		dao1.createTable();
		
	    String localeEs = "es_ES";
	    dao1.add(new BeanTest1("hello world", 0l, 1l, true, new Date()));
		dao1.add(new BeanTest1("edgar allan poe", 0l, 1l, true, new Date()));
		long anId = dao1.add(new BeanTest1("hi world", 0l, 12345l, true, new Date()));
		
		assertTrue(dao1.get(anId)!=null);
		assertTrue(dao1.getLocale(anId, Locale.US.toString())!=null);
		assertTrue(dao1.getLocale(anId, Locale.US.toString()).getStrField1().equals("hi world"));
		assertTrue(dao1.getLocale(anId, localeEs)==null);
				
		BeanTest1 obj = dao1.get(anId);
		obj.setStrField1("hola mundo");
//		assertTrue(!dao1.setLocale(obj, localeEs));
		
//		assertTrue(dao1.getLocale(anId, localeEs)!=null);
//		assertTrue(dao1.getLocale(anId, localeEs).getStrField1().equals("hola mundo"));
//		
//		//same ids
//		assertTrue(dao1.getLocale(anId, localeEs).getLongField1().equals(
//			dao1.get(anId).getLongField1()) && 
//			dao1.getLocale(anId, localeEs).getLongField1().equals(
//					dao1.getLocale(anId, Locale.US.toString()).getLongField1())); 
//		
//		obj.setStrField1("hola tierra");
//		assertTrue(dao1.setLocale(obj, localeEs));
//		assertTrue(dao1.getLocale(anId, localeEs).getStrField1().equals("hola tierra"));
//		
//		assertTrue(dao1.searchLocale(Util.<String>toOrderedMap(
//				"strField1", "hola"), localeEs).size()==1);
	}
	
	
	public void testBlob() throws Exception{
		Dao<BeanTest2> dao = new BeanDao<BeanTest2>(getValidConnectionGiver(), BeanTest2.class);
		
		//first we drop the table and then recreate the table in database for having a clean table to work with
		dao.dropTable(); 
		dao.createTable();
		
		//(String name, Integer age, Boolean gender, Date bornDate,	byte[] image
		long lauraId = dao.add(new BeanTest2("laura", 25, false, new Date(), "lauradata".getBytes()));
		dao.add(new BeanTest2("seba", 25, false, new Date(), "sebadata".getBytes()));
		
		assertEquals("lauradata", new String(dao.get(lauraId).getImage()));
	}
	
	
	public void testCompleteUseCase() throws Exception{
//common jdbc connection parameters
String url = "jdbc:mysql://localhost:3306/";
String dbName = "daotest1";
String driver = "com.mysql.jdbc.Driver";
String userName = "root";
String password = "root";

//now create a connection giver this object provides with connection and some 
//other util operations needed by the framework. in this case we use a common jdbc connection to a mysql database:
connectionGiver = new JDBCConnectionGiver(url, driver, dbName, userName, password);
		
//we are ready for reflecting simple java objects into database:

//create a Data access Object for the model clas BeanTest1. dao1 object can be used for storing, finding, adding, updating instances of BeanTest1 to/from database
Dao<BeanTest1> dao1 = new BeanDao<BeanTest1>(connectionGiver, BeanTest1.class);


//now ready to start doing some things
BeanTest1 bean1 = new BeanTest1("hello", 888l, true, new Date());//create a model
long newId = dao1.add(bean1); // add the object to database
		
BeanTest1 bean1Copy = dao1.get(newId); //get the just added object again in an other  java object

bean1Copy.setBoolField1(false);
dao1.update(bean1Copy); //update the database with changes to one instance
		
//		dao1.remove(bean1Copy); //remove the one added instance from database.
	}
	
	
	public void testCustomDaos() {
		// TODO Auto-generated method stub

	}
}
